#include "server-client-net.h"
#include "log.h"
#include "message-server-client.h"
#include <arpa/inet.h>

ServerClientNet::ServerClientNet() {
    socket_sender_ = new QUdpSocket(this);
    socket_receiver_ = NULL;
}

ServerClientNet::~ServerClientNet() {
    socket_sender_->close();
    socket_receiver_->close();
    delete socket_sender_;
    delete socket_receiver_;
}

void ServerClientNet::send_message(quint32 address, quint16 port, Message* message) {
    LOG(INFO) << "construim mesajulXX " << address << "|";
    const QByteArray* datagram = message->build_array();
    LOG(INFO) << "bav" << address;

    LOG(INFO) << "adresa la care se trimite e:";
    socket_sender_->writeDatagram(datagram->data(), datagram->size(), QHostAddress(address), port);

    delete datagram;
}

void ServerClientNet::recv_message(Message** message, quint32* address) {
    //LOG(INFO) << "server-client-net:recv_message:Am primit mesajul: ";
    if (!listening()) {
        LOG(INFO) << "nulul";
        return;
    }
    *message = NULL;
    quint16 port;
    if (socket_receiver_->hasPendingDatagrams()) {
        QByteArray *datagram = new QByteArray();
        datagram->resize(socket_receiver_->pendingDatagramSize());
        //LOG(INFO) << "Am facut resize la datagrama si are marimea " << datagram->size();
        QHostAddress qaddress;
        socket_receiver_->readDatagram(datagram->data(), datagram->size(), &qaddress, &port);

        *address = qaddress.toIPv4Address();

        // afisam mesajul trimis
        //LOG(INFO) << "afisam ce trimite " << datagram->size();
        //for (int i = 0; i < datagram->size(); ++i) {
        //    if (datagram->at(i) < 32 || datagram->at(i) > 127)
        //       std::cerr << ".";
        //    else
        //       std::cerr << datagram->at(i);
        //}
        //std::cout << "end" << std::endl;
        // TODO deharcodarea..
        *message = messages::bytearray_to_message(datagram);
        //message = new Message(messages::ACK_LOGIN);
        //LOG(INFO) << "Tipul mesajului: " << *message->type();
    }
}

void ServerClientNet::create_recv_socket(quint16 port)
{
    socket_receiver_ = new QUdpSocket(this);
    socket_receiver_->bind(port);
}

bool ServerClientNet::wait_for_ready_read()
{
    return socket_receiver_->waitForReadyRead(-1);
}

bool ServerClientNet::listening()
{
    return (socket_receiver_ != NULL);
}
